package com.ruoyi.system.service.impl;

import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.UniqueIdGenerator;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.api.domain.RegisterInfo;
import com.ruoyi.system.api.domain.SysTenant;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.mapper.SysTenantMapper;
import com.ruoyi.system.service.IDynamicSqlService;
import com.ruoyi.system.service.ISysTenantService;
import com.ruoyi.system.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;


/**
 * 租户Service业务层处理
 *
 * @author ruoyi
 * @date 2024-09-27
 */
@Service
@Slf4j
public class SysTenantServiceImpl implements ISysTenantService
{
    @Autowired
    private SysTenantMapper sysTenantMapper;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private IDynamicSqlService dynamicSqlService;
    /**
     * 查询租户
     *
     * @param id 租户主键
     * @return 租户
     */
    @Override
    public SysTenant selectSysTenantById(Long id)
    {
        return sysTenantMapper.selectSysTenantById(id);
    }

    /**
     * 查询租户列表
     *
     * @param sysTenant 租户
     * @return 租户
     */
    @Override
    public List<SysTenant> selectSysTenantList(SysTenant sysTenant)
    {
        return sysTenantMapper.selectSysTenantList(sysTenant);
    }

    /**
     * 新增租户
     *
     * @param registeinfo 注册信息
     * @return 返回租户编码
     */
    @Override
    @Transactional(rollbackFor={Exception.class,RuntimeException.class})
    public String insertSysTenant(RegisterInfo registeinfo)
    {
        SysTenant tenantInfo = new SysTenant();
        tenantInfo.setIndustry(registeinfo.getTenantInfo().getIndustry());
        tenantInfo.setEnterpriseName(registeinfo.getTenantInfo().getName());
        tenantInfo.setEnterpriseEmployeesNum(registeinfo.getTenantInfo().getEmployeeCount());
        tenantInfo.setCreateTime(DateUtils.getNowDate());
        tenantInfo.setEnterpriseCode(UniqueIdGenerator.getUniqueId(SysTenant.TENANT_CODE_LEN));

        if(sysTenantMapper.insertSysTenant(tenantInfo)==1){

            //注册用户信息,同步绑定租户
            SysUser regUserInfo = new SysUser();
            regUserInfo.setUserName(registeinfo.getUserInfo().getUsername());
            //第一个用户固定位租户管理员
            regUserInfo.setUserType(SecurityConstants.TENANT_ADMIN_USER_TYPE);
            regUserInfo.setPassword(SecurityUtils.encryptPassword(registeinfo.getUserInfo().getPassword()));
            log.info("原始密码:"+registeinfo.getUserInfo().getPassword()+",加密后密码："+regUserInfo.getPassword());
            regUserInfo.setEnterpriseCode(tenantInfo.getEnterpriseCode());
            regUserInfo.setNickName(registeinfo.getUserInfo().getUsername());
            regUserInfo.setPhonenumber(registeinfo.getUserInfo().getPhone());
            sysUserService.insertUser(regUserInfo);
            //初始化租户相关信息
            initTenantInfo(tenantInfo,regUserInfo);
            return tenantInfo.getEnterpriseCode();
        }else
            throw new ServiceException("新增租户失败!");
    }

    /**
     * 初始化租户信息：菜单，权限，角色等
     * @param tenantInfo
     * @param regUserInfo
     */
    private void initTenantInfo(SysTenant tenantInfo, SysUser regUserInfo) {
        String filePath = "/sql/tenantinit.sql";
        try  {
            InputStream inputStream = org.apache.commons.io.FileUtils.class.getResourceAsStream(filePath);
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
            List<String> sqlStatements = new ArrayList<>();
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                line = line.trim(); // 去除行首尾的空白字符
                if (line.isEmpty() || line.startsWith("--")) {
                    continue; // 跳过空行和注释
                }
                if (line.endsWith(";")) {
                    //去掉分号
                    sb.append(line).append(" ");
                    int pos = sb.lastIndexOf(";");
                    sb.setLength(pos);
                    //替换租户编码
                    String sql = sb.toString().replace("${enterpriseCode}",tenantInfo.getEnterpriseCode());
                    sql = sql.replace("${applicationCode}", SecurityConstants.IGNORE_APPLICATION_CODE);
                    //替换部门名称，用户名，手机号，邮箱
                    sql = sql.replace("${enterpriseName}",tenantInfo.getEnterpriseName());
                    sql = sql.replace("${userName}",regUserInfo.getUserName());
                    if(StringUtils.isNotEmpty(regUserInfo.getPhonenumber())) {
                        sql = sql.replace("${phone}", regUserInfo.getPhonenumber());
                    }else{
                        sql = sql.replace("${phone}", "");
                    }
                    if(StringUtils.isNotEmpty(regUserInfo.getEmail())) {
                        sql = sql.replace("${email}", regUserInfo.getEmail());
                    }else{
                        sql = sql.replace("${email}", "");
                    }
                    sqlStatements.add(sql);
                    sb.setLength(0); // 清空 StringBuilder
                }else{
                    sb.append(line).append(" ");
                }
            }
            inputStream.close();

            for (String sql : sqlStatements) {
                dynamicSqlService.executeSql(sql);
            }

        } catch (IOException e) {
            e.printStackTrace();
            log.error("初始化租户信息失败！",e);
            throw new ServiceException("初始化租户信息失败！");
        }
    }

    /**
     * 修改租户
     *
     * @param sysTenant 租户
     * @return 结果
     */
    @Override
    public int updateSysTenant(SysTenant sysTenant)
    {
        sysTenant.setUpdateTime(DateUtils.getNowDate());
        return sysTenantMapper.updateSysTenant(sysTenant);
    }

    /**
     * 批量删除租户
     *
     * @param ids 需要删除的租户主键
     * @return 结果
     */
    @Override
    public int deleteSysTenantByIds(Long[] ids)
    {
        return sysTenantMapper.deleteSysTenantByIds(ids);
    }

    /**
     * 删除租户信息
     *
     * @param id 租户主键
     * @return 结果
     */
    @Override
    public int deleteSysTenantById(Long id)
    {
        return sysTenantMapper.deleteSysTenantById(id);
    }
}
